package jmine.tec.di.metadata.impl;

import jmine.tec.annotations.Unmodifiable;
import jmine.tec.di.metadata.DependencyMetaData;
import jmine.tec.di.resolver.ObjectResolver;
import jmine.tec.di.scope.TypedScope;
import jmine.tec.di.type.TypeConvertionException;
import jmine.tec.di.wrapper.Wrapper;

/**
 * @author MarceloT
 */
@Unmodifiable
public class DependencyMetaDataImpl implements DependencyMetaData {

    private final String propertyName;

    private final ObjectResolver resolver;

    private final Wrapper wrapper;

    private final boolean required;

    private final Class<?> componentType;

    /**
     * @param propertyName o nome da propriedade
     * @param resolver o object resolver
     * @param required boolean
     * @param wrapper the wrapper
     * @param componentType o tipo
     */
    public DependencyMetaDataImpl(String propertyName, ObjectResolver resolver, boolean required, final Wrapper wrapper,
            Class<?> componentType) {
        super();
        this.propertyName = propertyName;
        this.resolver = resolver;
        this.required = required;
        this.wrapper = wrapper;
        this.componentType = componentType;
    }

    /**
     * @return the propertyName
     */
    public String getPropertyName() {
        return this.propertyName;
    }

    /**
     * @return the resolver
     */
    public ObjectResolver getResolver() {
        return this.resolver;
    }

    /**
     * @return the required
     */
    public boolean isRequired() {
        return this.required;
    }

    /**
     * @return {@link Wrapper}
     */
    public Wrapper getWrapper() {
        return this.wrapper;
    }

    /**
     * @param scope the scope
     * @return Object
     * @throws TypeConvertionException e
     */
    public Object resolveObjectWrap(TypedScope scope) throws TypeConvertionException {
        try {
            return this.resolver.resolveObject(scope, this.wrapper, this.componentType);
        } catch (TypeConvertionException e) {
            throw e;
        }
    }

    /**
     * @param scope {@link TypedScope}
     * @return boolean
     */
    public boolean isResolvable(TypedScope scope) {
        return this.resolver.isResolvable(scope);
    }

    /**
     * @return the componentType
     */
    public Class<?> getComponentType() {
        return this.componentType;
    }

}
